package com.lianda.json;


import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

//参考：https://blog.csdn.net/z69183787/article/details/79317443
//https://www.jianshu.com/p/590508f32b76
public class JacksonTest {

    static Map<String, String> keyMap = new HashMap<String, String>(){{
        put("name", "MyName");
        put("age", "MyAge");
        put("kind", "MyKind");
    }};

    static Map<String, String> valueMap = new HashMap<String, String>(){{
        put("cat", "dog");
        put("123", "123dog");
        put("fuck", "peace");
        put("gan", "peace");
    }};


    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
//        module.addKeyDeserializer(String.class, new MapKeyDeserializer());
        module.addDeserializer(Map.class,
                new MyJsonDeserializer());
        mapper.registerModule(module);

        String json = "{\"name\":\"abc\",\"age\":\"123\",\"info\":[{\"message\":\"cat\",\"kind\":\"asd\"},{\"message\":\"cat\",\"kind\":\"dedsf\"}]}";
        String json2 = "{\"name\":\"abc\",\"age\":\"123\",\"info\":[\"fuck\",\"gan\"]}";

        long start = System.currentTimeMillis();
        Map<String, Object> map = null;
        for (int i = 0; i < 10000000; i++) {
            map = mapper.readValue(json, new TypeReference<Map<String, Object>>(){});
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时========>" + (end - start) + "ms");
    }

    //key的反序列化
    static class MapKeyDeserializer extends KeyDeserializer {
        @Override
        public Object deserializeKey(String key, DeserializationContext deserializationContext) throws IOException {
            String newKey = keyMap.get(key);
            if (newKey != null && !newKey.equals("")) {
                return newKey;
            }
            return key;
        }
    }


    //自定义反序列化
    static class MyJsonDeserializer extends JsonDeserializer {
        static final ObjectMapper objectMapper = new ObjectMapper();

        @Override
        public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
            Map<String, Object> result = new HashMap<>();
            convertNode(node, result);
            return result;
        }

        //转换结果
        private void convertNode(JsonNode objNode, Map<String, Object> result) throws IOException {
            Iterator<Map.Entry<String, JsonNode>> iter = objNode.fields();
            while (iter.hasNext()) {
                Map.Entry<String, JsonNode> entry = iter.next();
                String newKey = MapUtils.getString(keyMap, entry.getKey(), entry.getKey());
                result.put(newKey, entry.getValue());

                //转换数组
                if (entry.getValue().getNodeType() == JsonNodeType.ARRAY) {
                    result.put(newKey, convertArrayNode((ArrayNode) entry.getValue()));
                }
                //转换值
                if (entry.getValue().getNodeType() == JsonNodeType.STRING) {
                    String newValue = MapUtils.getString(valueMap, entry.getValue().textValue(), entry.getValue().textValue());
                    result.put(newKey, newValue);
                }
            }
        }

        //转换ObjNode
        private void convertObjNode(JsonNode objNode, ObjectNode result) throws IOException {
            Iterator<Map.Entry<String, JsonNode>> iter = objNode.fields();
            while (iter.hasNext()) {
                Map.Entry<String, JsonNode> entry = iter.next();
                String newKey = MapUtils.getString(keyMap, entry.getKey(), entry.getKey());
                result.put(newKey, entry.getValue());

                //转换数组
                if (entry.getValue().getNodeType() == JsonNodeType.ARRAY) {
                    result.put(newKey, convertArrayNode((ArrayNode) entry.getValue()));
                }

                //转换值
                if (entry.getValue().getNodeType() == JsonNodeType.STRING) {
                    String newValue = MapUtils.getString(valueMap, entry.getValue().textValue(), entry.getValue().textValue());
                    result.put(newKey, newValue);
                }
            }
        }

        private ArrayNode convertArrayNode(ArrayNode arrayNode) throws IOException {
            ArrayNode resultNode = objectMapper.createArrayNode();
            Iterator<JsonNode> array = arrayNode.elements();
            while (array.hasNext()) {
                JsonNode tempNode = array.next();
                if (tempNode.getNodeType() == JsonNodeType.OBJECT) {
                    ObjectNode tempResult =objectMapper.createObjectNode();
                    convertObjNode(tempNode, tempResult);
                    resultNode.add(tempResult);
                }
                if (tempNode.getNodeType() == JsonNodeType.ARRAY) {
                    System.out.println("===2");
                }
                if (tempNode.getNodeType() == JsonNodeType.STRING) {
                    String orgValue = tempNode.textValue();
                    String newValue = MapUtils.getString(valueMap, orgValue, orgValue);
                    //新建节点
                    tempNode = objectMapper.createObjectNode().textNode(newValue);
                }
                resultNode.add(tempNode);
            }
            return resultNode;
        }
    }
}
